

#include "campaignscene.h"
#include "campaignintrolayer.h"
#include "resourcemanager.h"
#include "log.h"
#include "gamemanager.h"
#include "gamedatamanager.h"
#include "gamescene.h"
#include "formationscene.h"
#include "CCSkeletonCache.h"
#include "goldcoinscene.h"
#include "messagequeue.h"
#include "armiesscene.h"


static const int CHAPTER_WIDTH = 590;
static const int CHAPTER_HEIGHT = 82;
static const int CHAPTER_SPACE = 5;

static const float SCROLL_THRESHOLD = 5.0f;

CampaignScene::CampaignScene():
_layer(nullptr)
, _selectedTabIndex(0)
, _selectedChapterIndex(0)
, _touchedTabButtonIndex(-1)
, _touchPlace(CampaignSceneTouchPlace::blank) {

}

CampaignScene::~CampaignScene() {
}

bool CampaignScene::init() {
	if (!CCScene::init()) {
		return false;
	}

	_layer = CCLayer::create();
	addChild(_layer);

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
	CCSprite *spr = CCSprite::create("textures/ui_bg.png");
#else
	CCSprite *spr = CCSprite::create("textures/ui_bg.png");
#endif

	spr->setAnchorPoint(CCPointZero);

	CCSize size = spr->getContentSize();
	spr->setScaleX(GM->screenSize.width / size.width);
	spr->setScaleY(GM->screenSize.height / size.height);
	_layer->addChild(spr);

	CCMenuItemSprite *btnExit = RM->makeBackButton(this, menu_selector(CampaignScene::onClose), _layer, false);
	btnExit->setPosition(XY_SCALE(45, 535));

	auto btnMoney = RM->makeButton("money_pad.png", nullptr, nullptr, this, menu_selector(CampaignScene::onRecharge), _layer);
	btnMoney->setPosition(XY_SCALE(GameManager::BASE_WIDTH, GameManager::BASE_HEIGHT - 30));
	btnMoney->setAnchorPoint(ccp(1.0f, 0.5f));

	sprintf(buf, "%d", GDM->money);
	_labelMoney = CCLabelTTF::create(buf, "", 24);
	_labelMoney->setPosition(ccp(76, 30));
	_labelMoney->setColor(ccc3(237, 199, 143));
	_labelMoney->setAnchorPoint(ccp(0.5f, 0.5f));
	btnMoney->addChild(_labelMoney);

	int x = 118;
	int arr_y_pos[] = {400, 300, 200};

	for (int i = 0; i < CAMPAIGN_EPISODE_COUNT; i++) {
		if (i == 0) {
			_tabButtons[i] = MAKE_SPRITE("button/round_button_1.png");
		} else {
			_tabButtons[i] = MAKE_SPRITE("button/round_button_0.png");
		}

		_tabButtons[i]->setPosition(XY_SCALE(x, arr_y_pos[i]));
		_tabButtons[i]->setAnchorPoint(ccp(1.0f, 0.5f));

		_layer->addChild(_tabButtons[i]);

		sprintf(buf, "act%d.png", i + 1);
		CCSprite *spr = MAKE_SPRITE(buf);
		spr->setScale(1.0f);
		spr->setPosition(ccp(48, 48));
		_tabButtons[i]->addChild(spr);
	}

	cocos2d::extension::CCScale9Sprite *sprCampaignFrame = cocos2d::extension::CCScale9Sprite::create("textures/frame.png", CCRectMake(0, 0, 96, 96), CCRectMake(32, 32, 32, 32));
	sprCampaignFrame->setContentSize(CCSizeMake(X_SCALE(816), Y_SCALE(495)));
	sprCampaignFrame->setPosition(XY_SCALE(120, 0));
	sprCampaignFrame->setAnchorPoint(CCPointZero);
	_layer->addChild(sprCampaignFrame);

	CCSize bgSize = CCSizeMake(X_SCALE(765), Y_SCALE(450));
	_actsViewBg = cocos2d::extension::CCScale9Sprite::create("textures/pad_bg.png", CCRectMake(0, 0, 225, 225), CCRectMake(100, 100, 25, 25));
	_actsViewBg->setContentSize(bgSize);
	_actsViewBg->setPosition(XY_SCALE(148, 20));
	_actsViewBg->setAnchorPoint(ccp(0.0f, 0.0f));
	_layer->addChild(_actsViewBg);

	createActs();

	scheduleUpdate();

	return true;
}

void CampaignScene::update(float dt) {
	handleMessage(dt);
}


void CampaignScene::startBattle(CCObject* sender) {
	CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
	CCDirector::sharedDirector()->getKeypadDispatcher()->removeDelegate(this);

	CCLayerColor* maskLayer = CCLayerColor::create(ccc4(10, 10, 10, 200));
	addChild(maskLayer);

	CampaignIntroLayer* layer = CampaignIntroLayer::create();
	FormationInfo *f = GDM->loadCampaignFormation(_selectedTabIndex, _selectedChapterIndex);
	layer->campaignFormation = f;

	const CampaignInfo& campaign = GDM->campaigns[_selectedTabIndex];
	auto chapterInfo = campaign.chapters[_selectedChapterIndex];
	layer->setCampaignInfo(chapterInfo.title.c_str(), chapterInfo.text.c_str());
	maskLayer->addChild(layer);
}

void CampaignScene::onClose(CCObject *sender) {
	CCDirector::sharedDirector()->replaceScene(ArmiesScene::create());
}

bool CampaignScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
	auto pt = pTouch->getLocation();
	if (_actsViewBg->hitTest(pt)) {
		_touchPlace = CampaignSceneTouchPlace::episode_view;

		const vector<CCMenuItemSprite *>& arr = _arrSprites[_selectedTabIndex];
		int index = 0;
		for (auto item : arr) {
			if (item->hitTest(pt)) {
				_touchPlace = CampaignSceneTouchPlace::chapter_item;
				_selectedChapterIndex = index;
				_touchStartPos = pt;

//				item->setDisplayFrame(MAKE_SPRITEFRAME("campaign_item_bg1.png"));
				break;
			}

			index++;
		}
	} else {
		for (int i = 0; i < CAMPAIGN_EPISODE_COUNT; i++) {
			if (_tabButtons[i]->hitTest(pt)) {
				_touchPlace = CampaignSceneTouchPlace::tab_button;
				_touchedTabButtonIndex = i;
				break;
			}
		}
	}

	return true;
}

void CampaignScene::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
	auto pt = pTouch->getLocation();
	switch (_touchPlace) {
		case CampaignSceneTouchPlace::episode_view:
			scrollEpisodeView(pTouch->getDelta().y);
	        break;
		case CampaignSceneTouchPlace::chapter_item: {
			float dy = static_cast<float>(fabs(pt.y - _touchStartPos.y));
			if (dy > SCROLL_THRESHOLD) {
				_touchPlace = CampaignSceneTouchPlace::episode_view;
			}

			break;
		}
		default:
			break;
	}
}

void CampaignScene::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
	auto pt = pTouch->getLocation();
	switch(_touchPlace) {
		case CampaignSceneTouchPlace::chapter_item:{
			const vector<CCMenuItemSprite*>& arr = _arrSprites[_selectedTabIndex];
//			arr[_selectedChapterIndex]->setDisplayFrame(MAKE_SPRITEFRAME("campaign_item_bg.png"));
			startBattle(nullptr);
			break;
		}
		case CampaignSceneTouchPlace::tab_button:
			switchCampaignView();
			break;
		default:break;
	}

	_touchedTabButtonIndex = -1;
}

void CampaignScene::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) {
	_touchedTabButtonIndex = -1;
	_selectedChapterIndex = -1;
}

void CampaignScene::createActs() {
	CCSize bgSize = _actsViewBg->getContentSize();

	for (int i = 0; i < CAMPAIGN_EPISODE_COUNT; i++) {
		const CampaignInfo& campaign = GDM->campaigns[i];

		CCSize size(X_SCALE(CHAPTER_WIDTH), Y_SCALE((CHAPTER_HEIGHT + CHAPTER_SPACE) * campaign.chapters.size() - CHAPTER_SPACE));
		CCSize clippingSize = CCSizeMake(size.width, Y_SCALE(398));

		CCClippingNode *clippingNode = CCClippingNode::create();
		clippingNode->setAnchorPoint(ccp(0.5f, 0.5f));
		clippingNode->setPosition(ccp(_actsViewBg->getPositionX() + bgSize.width / 2, _actsViewBg->getPositionY() + bgSize.height / 2));
		clippingNode->setContentSize(clippingSize);

		CCPoint vertices[] = {
				ccp(0, 0),
				ccp(clippingSize.width, 0),
				ccp(clippingSize.width, clippingSize.height),
				ccp(0, clippingSize.height)
		};

		ccColor4F black = {1, 1, 1, 1};
		CCDrawNode *stencil = CCDrawNode::create();
		stencil->drawPolygon(vertices, 4, black, 1, black);
		clippingNode->setStencil(stencil);

		_layer->addChild(clippingNode);

		CCLayer *layer = CCLayer::create();
		layer->setAnchorPoint(CCPointZero);
		layer->setContentSize(size);
		layer->setPosition(ccp(0, clippingSize.height - size.height));
		layer->setVisible(false);

		clippingNode->addChild(layer);
		_layerEpisodes[i] = layer;

		float x = X_SCALE(CHAPTER_WIDTH / 2);
		float y = Y_SCALE(CHAPTER_HEIGHT / 2);

		for (size_t j = 0; j < campaign.chapters.size(); j++) {
			const ChapterInfo& chapter = campaign.chapters[j];

			auto pt = ccp(x, size.height - y);

			cocos2d::extension::CCScale9Sprite *itemBgNormal = cocos2d::extension::CCScale9Sprite::create("textures/item_bg.png", CCRectMake(0, 0, 80, 80), CCRectMake(20, 20, 40, 40));
			itemBgNormal->setContentSize(CCSizeMake(X_SCALE(CHAPTER_WIDTH), Y_SCALE(60)));

			cocos2d::extension::CCScale9Sprite *itemBgHighlight = cocos2d::extension::CCScale9Sprite::create("textures/highlight_item_bg.png", CCRectMake(0, 0, 80, 80), CCRectMake(20, 20, 40, 40));
			itemBgHighlight->setContentSize(CCSizeMake(X_SCALE(CHAPTER_WIDTH), Y_SCALE(60)));

			CCMenuItemSprite *button = CCMenuItemSprite::create(itemBgNormal, itemBgHighlight, nullptr, this, menu_selector(CampaignScene::startBattle));
			button->setScale(GM->minscale);
			button->setPosition(pt);

			CCMenu *menu = CCMenu::create(button, nullptr);
			menu->setPosition(CCPointZero);
			layer->addChild(menu);

			CCSprite *itemIcon = MAKE_SPRITE("campaign_icon_1.png");
			itemIcon->setPosition(ccp(48, 38));
			button->addChild(itemIcon);

			CCLabelTTF *labelTitle = CCLabelTTF::create(chapter.title.c_str(), "", 32);
			labelTitle->setPosition(ccp(100, 36));
			labelTitle->setColor(ccc3(24, 6, 2));
			labelTitle->setAnchorPoint(ccp(0.0f, 0.5f));
			button->addChild(labelTitle);

			_arrSprites[i].push_back(button);

			y += Y_SCALE(CHAPTER_HEIGHT + CHAPTER_SPACE);
		}
	}

	_layerEpisodes[0]->setVisible(true);
}

void CampaignScene::switchCampaignView() {
	_tabButtons[_selectedTabIndex]->setDisplayFrame(MAKE_SPRITEFRAME("button/round_button_0.png"));
	_layerEpisodes[_selectedTabIndex]->setVisible(false);
	_selectedTabIndex = _touchedTabButtonIndex;
	_layerEpisodes[_selectedTabIndex]->setVisible(true);

	_tabButtons[_selectedTabIndex]->setDisplayFrame(MAKE_SPRITEFRAME("button/round_button_1.png"));
}

void CampaignScene::scrollEpisodeView(float distance) {
	CCLayer *layer = _layerEpisodes[_selectedTabIndex];

	CCPoint newPt = layer->getPosition();
	newPt.y += distance;

	float miny = layer->getParent()->getContentSize().height - layer->getContentSize().height;
	if (newPt.y < miny) {
		newPt.y = miny;
	}
	if (newPt.y > 0) {
		newPt.y = 0;
	}

	layer->setPosition(newPt);
}

void CampaignScene::keyBackClicked() {
	onClose(nullptr);
}

void CampaignScene::keyMenuClicked() {

}

void CampaignScene::onRecharge(CCObject *sender) {
	GoldCoinScene* scene = GoldCoinScene::create();
	CCDirector::sharedDirector()->pushScene(scene);
}

void CampaignScene::onEnter() {
	CCScene::onEnter();

	sprintf(buf, "%d", GDM->money);
	_labelMoney->setString(buf);

	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -1, true);
	CCDirector::sharedDirector()->getKeypadDispatcher()->addDelegate(this);
}

void CampaignScene::onExit() {
	CCScene::onExit();

	CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
	CCDirector::sharedDirector()->getKeypadDispatcher()->removeDelegate(this);
}

void CampaignScene::handleMessage(float ticks) {
	MessageData *msg = PEEK_MSG(MessageTarget::game_scene);
	if (msg) {
		switch (msg->key) {
			case MessageFlag::model_layer_closed:
				CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -1, true);
		        CCDirector::sharedDirector()->getKeypadDispatcher()->addDelegate(this);
				break;
			default:
				break;
		}

		POP_MSG(MessageTarget::game_scene);
	}
}
